﻿/*
 * Copyright 2020, Guan Xiaopeng
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
 
using System;
using System.Collections.Generic;

namespace XPRPC
{
    /// <summary>
    /// 用于管理多个Service的生命周期，并对客户端进行认证
    /// </summary>
    public interface IServiceManager : IDisposable
    {
        /// <summary>
        /// 认证客户端
        /// </summary>
        /// <param name="clientID">预先分配的客户端ID</param>
        /// <param name="secretKey">用于识别该客户端的安全码</param>
        /// <returns></returns>
        bool AuthenticateClient(string clientID, string secretKey);

        /// <summary>
        /// 注册一个服务
        /// </summary>
        /// <param name="descriptor">服务描述符</param>
        /// <returns>
        /// 成功返回 serviceToken, 用于后续操纵该服务;
        /// 失败返回空字串
        /// </returns>
        string AddService(ServiceDescriptor descriptor);

        /// <summary>
        /// 注销一个服务
        /// </summary>
        /// <param name="name">服务名</param>
        /// <param name="serviceToken">AddService 返回的安全令牌</param>
        void RemoveService(string name, string serviceToken);

        /// <summary>
        /// 报告一个服务当前健康运行。Service Manager会监控所有Service，
        /// 当service未能在一定时间间隔（可配置）内报告健康，则会被判定为失效，将被
        /// 从服务清单中移除，不能再被客户端查询到。服务提供方应该定时调用此方法报告
        /// 健康。
        /// </summary>
        /// <param name="name">服务名</param>
        /// <param name="serviceToken">AddService 返回的安全令牌</param>
        void ReportServiceHealthy(string name, string serviceToken);

        /// <summary>
        /// 查询一个当前客户端可访问服务
        /// </summary>
        /// <param name="name">服务名称</param>
        /// <returns>
        /// 若服务存在且能够访问，则返回该服务的描述符，否则返回一个
        /// 各字段保持default值的ServiceDescriptor
        /// </returns>
        ServiceDescriptor GetService(string name);

        /// <summary>
        /// 查询全部当前客户端可访问服务
        /// </summary>
        /// <returns>服务描述符列表</returns>
        List<ServiceDescriptor> ListService();

        event EventHandler<ServiceDeadEventArgs> ServiceDeadEvent;
    }

    public static class ServiceManagerExtension
    {
        public static bool ServiceExists(this IServiceManager serviceManager, string servieName)
        {
            return !string.IsNullOrEmpty(serviceManager.GetService(servieName).Name);
        }
    }

    [Serializable]
    public sealed class ServiceDeadEventArgs: EventArgs
    {
        public string ServiceName {get; set;}
    }
}
